<template>
    <input 
        type="text" 
        ref="inputRef" 
        v-bind="$attrs" 
        :value="modelValue"
        @input="handleInput"
        @change="handleChange"
        @blur="handleBlur"
    /> 
    <span v-if="errorMessage" class="error-msg">{{ errorMessage }}</span>
</template>
<script setup lang='ts'>

import { ref, onMounted, watch, inject } from 'vue'
import type { RuleItem } from './Form.vue'

// 定义组件属性
const props = defineProps<{
    name: string; // 输入框名称，用于关联规则
    modelValue: string; // v-model绑定值
    rules?: RuleItem[]; // 组件可以自己指定规则，也可以从表单继承
}>();

// 定义事件
const emit = defineEmits<{
    'update:modelValue': [value: string];
}>();

// 从父级Form组件注入上下文
const formContext = inject<{
    registerInput: (name: string, component: any) => void;
    handleValidation: (name: string, isValid: boolean, errorMsg: string) => void;
    rules: RuleItem[];
}>('formContext');

const inputRef = ref<HTMLInputElement | null>(null);
const errorMessage = ref('');

// 获取有效的规则列表（组件自身规则优先，否则使用表单规则）
const getEffectiveRules = () => {
    if (props.rules) return props.rules;
    return formContext?.rules.filter(rule => rule.name === props.name) || [];
};

// 校验函数
const validate = (trigger: string): boolean => {
    const rules = getEffectiveRules();
    if (rules.length === 0) return true;
    
    // 查找匹配当前触发条件的规则
    const matchedRules = rules.filter(rule => 
        rule.name === props.name && rule.trigger === trigger
    );
    
    // 遍历规则进行校验
    for (const rule of matchedRules) {
        const value = props.modelValue;
        
        // 进行校验
        if (rule.type === 'Required' && !value.trim()) {
            errorMessage.value = rule.errorMsg;
            formContext?.handleValidation(props.name, false, rule.errorMsg);
            return false;
        }
        
        if (rule.type === 'Numbric' && value && !/^\d+$/.test(value)) {
            errorMessage.value = rule.errorMsg;
            formContext?.handleValidation(props.name, false, rule.errorMsg);
            return false;
        }
    }
    
    // 校验通过
    errorMessage.value = '';
    formContext?.handleValidation(props.name, true, '');
    return true;
};

// 事件处理函数
const handleInput = (event: Event) => {
    const value = (event.target as HTMLInputElement).value;
    emit('update:modelValue', value);
    validate('Input');
};

const handleChange = () => {
    validate('Change');
};

const handleBlur = () => {
    validate('Blur');
};

// 监听modelValue变化，当值被外部修改时重新校验
watch(() => props.modelValue, () => {
    // 当值被清空时，清除错误信息
    if (!props.modelValue.trim()) {
        errorMessage.value = '';
        formContext?.handleValidation(props.name, true, '');
    }
});

// 暴露validate方法给父组件调用
defineExpose({
    validate
});

onMounted(() => {
    // 在挂载时向表单注册自身
    if (formContext) {
        formContext.registerInput(props.name, {
            validate
        });
    }
});
</script>

<style scoped>
.error-msg {
    color: #f56c6c;
    font-size: 12px;
    line-height: 1;
    padding-top: 4px;
    margin-left: 8px;
}

input {
    padding: 4px 8px;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    outline: none;
    transition: border-color 0.2s;
}

input:focus {
    border-color: #409eff;
}
</style>